<template>
  <div class="system-monitor">
    <el-container>
      <el-header>
        <div class="header-content">
          <h1>爬虫监控与错误日志</h1>
          <div class="header-actions">
            <el-button type="primary" @click="refreshData">
              <el-icon><Refresh /></el-icon>
              刷新数据
            </el-button>
            <el-button @click="clearLogs">
              <el-icon><Delete /></el-icon>
              清空日志
            </el-button>
          </div>
        </div>
      </el-header>
      
      <el-main>
        <!-- 爬虫状态概览 -->
        <el-row :gutter="20" class="status-cards">
          <el-col :span="6">
            <el-card class="status-card">
              <div class="card-content">
                <div class="card-icon">
                  <el-icon size="40" :color="systemStatus.crawlerRunning ? '#67C23A' : '#F56C6C'">
                    <Monitor />
                  </el-icon>
                </div>
                <div class="card-info">
                  <div class="card-title">爬虫状态</div>
                  <div class="card-value">
                    <el-tag :type="systemStatus.crawlerRunning ? 'success' : 'info'">
                      {{ systemStatus.crawlerRunning ? '运行中' : '已停止' }}
                    </el-tag>
                  </div>
                </div>
              </div>
            </el-card>
          </el-col>
          
          <el-col :span="6">
            <el-card class="status-card">
              <div class="card-content">
                <div class="card-icon">
                  <el-icon size="40" color="#67C23A"><Check /></el-icon>
                </div>
                <div class="card-info">
                  <div class="card-title">成功抓取</div>
                  <div class="card-value">{{ systemStatus.successCount }}</div>
                </div>
              </div>
            </el-card>
          </el-col>
          
          <el-col :span="6">
            <el-card class="status-card">
              <div class="card-content">
                <div class="card-icon">
                  <el-icon size="40" color="#F56C6C"><Close /></el-icon>
                </div>
                <div class="card-info">
                  <div class="card-title">错误数量</div>
                  <div class="card-value">{{ systemStatus.errorCount }}</div>
                </div>
              </div>
            </el-card>
          </el-col>
          
          <el-col :span="6">
            <el-card class="status-card">
              <div class="card-content">
                <div class="card-icon">
                  <el-icon size="40" color="#409EFF"><Clock /></el-icon>
                </div>
                <div class="card-info">
                  <div class="card-title">运行时长</div>
                  <div class="card-value">{{ systemStatus.uptime }}</div>
                </div>
              </div>
            </el-card>
          </el-col>
        </el-row>

        <!-- 数据质量统计 -->
        <el-card class="quality-section">
          <template #header>
            <span>数据质量统计</span>
          </template>
          <el-row :gutter="20">
            <el-col :span="8">
              <div class="quality-item">
                <div class="quality-title">今日抓取</div>
                <div class="quality-value">{{ systemStatus.todayScraped }}</div>
              </div>
            </el-col>
            <el-col :span="8">
              <div class="quality-item">
                <div class="quality-title">总商品数</div>
                <div class="quality-value">{{ systemStatus.totalProducts }}</div>
              </div>
            </el-col>
            <el-col :span="8">
              <div class="quality-item">
                <div class="quality-title">成功率</div>
                <div class="quality-value">
                  {{ systemStatus.totalProducts > 0 ? Math.round((systemStatus.successCount / systemStatus.totalProducts) * 100) : 0 }}%
                </div>
              </div>
            </el-col>
          </el-row>
        </el-card>

        <!-- 错误日志 -->
        <el-card class="log-section">
          <template #header>
            <span>错误日志</span>
            <div style="float: right;">
              <el-select v-model="logLevel" placeholder="日志级别" style="width: 120px; margin-right: 10px;">
                <el-option label="全部" value="all" />
                <el-option label="错误" value="error" />
                <el-option label="警告" value="warning" />
                <el-option label="信息" value="info" />
              </el-select>
              <el-button size="small" @click="exportLogs">
                <el-icon><Download /></el-icon>
                导出日志
              </el-button>
            </div>
          </template>
          
          <div class="log-container">
            <div 
              v-for="log in filteredLogs" 
              :key="log.id" 
              class="log-item"
              :class="`log-${log.level}`"
            >
              <div class="log-header">
                <div class="log-time">{{ formatTime(log.timestamp) }}</div>
                <div class="log-level">
                  <el-tag :type="getLogLevelType(log.level)" size="small">
                    {{ log.level.toUpperCase() }}
                  </el-tag>
                </div>
                <div class="log-spider">{{ log.spider }}</div>
              </div>
              <div class="log-message">{{ log.message }}</div>
              <div v-if="log.details && Object.keys(log.details).length > 0" class="log-details">
                <el-button size="small" @click="toggleDetails(log.id)">
                  {{ expandedDetails.includes(log.id) ? '隐藏详情' : '显示详情' }}
                </el-button>
                <div v-if="expandedDetails.includes(log.id)" class="details-content">
                  <pre>{{ JSON.stringify(log.details, null, 2) }}</pre>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 日志分页 -->
          <div class="log-pagination">
            <el-pagination
              v-model:current-page="logPage"
              v-model:page-size="logPageSize"
              :page-sizes="[50, 100, 200]"
              :total="totalLogs"
              layout="total, sizes, prev, pager, next, jumper"
              @size-change="handleLogSizeChange"
              @current-change="handleLogPageChange"
            />
          </div>
        </el-card>
      </el-main>
    </el-container>
  </div>
</template>

<script>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import axios from 'axios'

export default {
  name: 'SystemMonitor',
  setup() {
    const systemStatus = ref({
      crawlerRunning: false,
      successCount: 0,
      errorCount: 0,
      todayScraped: 0,
      totalProducts: 0,
      uptime: '0天0小时0分钟'
    })

    const systemLogs = ref([])
    const logLevel = ref('all')
    const logPage = ref(1)
    const logPageSize = ref(100)
    const totalLogs = ref(0)
    const expandedDetails = ref([])

    const filteredLogs = computed(() => {
      if (logLevel.value === 'all') {
        return systemLogs.value
      }
      return systemLogs.value.filter(log => log.level === logLevel.value)
    })

    let refreshTimer = null

    const fetchSystemStatus = async () => {
      try {
        const response = await axios.get('/api/monitor/status')
        systemStatus.value = response.data
      } catch (error) {
        console.error('获取系统状态失败:', error)
      }
    }

    const fetchSystemLogs = async () => {
      try {
        const response = await axios.get('/api/monitor/logs', {
          params: {
            page: logPage.value,
            pageSize: logPageSize.value,
            level: logLevel.value === 'all' ? '' : logLevel.value
          }
        })
        systemLogs.value = response.data.logs
        totalLogs.value = response.data.total
      } catch (error) {
        console.error('获取系统日志失败:', error)
      }
    }

    const refreshData = () => {
      fetchSystemStatus()
      fetchSystemLogs()
    }

    const clearLogs = async () => {
      try {
        await axios.delete('/api/monitor/logs')
        ElMessage.success('日志已清空')
        fetchSystemLogs()
      } catch (error) {
        ElMessage.error('清空日志失败')
      }
    }

    const exportLogs = () => {
      const logsText = systemLogs.value.map(log => 
        `[${log.timestamp}] [${log.level.toUpperCase()}] ${log.message}`
      ).join('\n')
      
      const blob = new Blob([logsText], { type: 'text/plain' })
      const url = URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = `spider_logs_${new Date().toISOString().split('T')[0]}.txt`
      a.click()
      URL.revokeObjectURL(url)
    }

    const toggleDetails = (logId) => {
      const index = expandedDetails.value.indexOf(logId)
      if (index > -1) {
        expandedDetails.value.splice(index, 1)
      } else {
        expandedDetails.value.push(logId)
      }
    }

    const formatTime = (timestamp) => {
      if (!timestamp) return ''
      try {
        const date = new Date(timestamp)
        return date.toLocaleString('zh-CN')
      } catch {
        return timestamp
      }
    }

    const getLogLevelType = (level) => {
      const types = {
        'error': 'danger',
        'warning': 'warning',
        'info': 'info',
        'debug': ''
      }
      return types[level] || 'info'
    }

    const handleLogSizeChange = (size) => {
      logPageSize.value = size
      logPage.value = 1
      fetchSystemLogs()
    }

    const handleLogPageChange = (page) => {
      logPage.value = page
      fetchSystemLogs()
    }

    onMounted(() => {
      refreshData()
      // 每30秒自动刷新
      refreshTimer = setInterval(refreshData, 30000)
    })

    onUnmounted(() => {
      if (refreshTimer) {
        clearInterval(refreshTimer)
      }
    })

    return {
      systemStatus,
      systemLogs,
      logLevel,
      logPage,
      logPageSize,
      totalLogs,
      expandedDetails,
      filteredLogs,
      refreshData,
      clearLogs,
      exportLogs,
      toggleDetails,
      formatTime,
      getLogLevelType,
      handleLogSizeChange,
      handleLogPageChange
    }
  }
}
</script>

<style scoped>
.system-monitor {
  height: 100vh;
  background-color: #f5f5f5;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 100%;
}

.header-content h1 {
  margin: 0;
  color: #333;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.status-cards {
  margin-bottom: 20px;
}

.status-card {
  height: 120px;
}

.card-content {
  display: flex;
  align-items: center;
  height: 100%;
}

.card-icon {
  margin-right: 15px;
}

.card-info {
  flex: 1;
}

.card-title {
  font-size: 14px;
  color: #666;
  margin-bottom: 8px;
}

.card-value {
  font-size: 24px;
  font-weight: bold;
  color: #333;
}

.quality-section {
  margin-bottom: 20px;
}

.quality-item {
  text-align: center;
  padding: 20px;
}

.quality-title {
  font-size: 14px;
  color: #666;
  margin-bottom: 10px;
}

.quality-value {
  font-size: 28px;
  font-weight: bold;
  color: #409EFF;
}

.log-section {
  margin-bottom: 20px;
}

.log-container {
  max-height: 600px;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 10px;
}

.log-item {
  margin-bottom: 15px;
  padding: 15px;
  border-radius: 4px;
  border-left: 4px solid #e4e7ed;
}

.log-item.log-error {
  background-color: #fef0f0;
  border-left-color: #f56c6c;
}

.log-item.log-warning {
  background-color: #fdf6ec;
  border-left-color: #e6a23c;
}

.log-item.log-info {
  background-color: #f0f9ff;
  border-left-color: #409eff;
}

.log-header {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  gap: 15px;
}

.log-time {
  font-size: 12px;
  color: #999;
  min-width: 150px;
}

.log-spider {
  font-size: 12px;
  color: #666;
  background-color: #f5f5f5;
  padding: 2px 8px;
  border-radius: 3px;
}

.log-message {
  font-size: 14px;
  color: #333;
  line-height: 1.5;
  margin-bottom: 8px;
}

.log-details {
  margin-top: 10px;
}

.details-content {
  margin-top: 10px;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border: 1px solid #e9ecef;
}

.details-content pre {
  margin: 0;
  font-size: 12px;
  color: #666;
  white-space: pre-wrap;
  word-break: break-all;
}

.log-pagination {
  margin-top: 20px;
  text-align: center;
}
</style> 